import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  OneToMany,
  Index,
} from 'typeorm';
import { ApiProperty } from '@nestjs/swagger';
import { Participant } from './participant.entity';

@Entity('rooms')
@Index(['createdAt'])
@Index(['expiresAt'])
export class Room {
  @ApiProperty({ description: '房间ID' })
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ApiProperty({ description: '房间名称', required: false })
  @Column({ type: 'varchar', length: 100, nullable: true })
  name?: string;

  @ApiProperty({ description: '房间描述', required: false })
  @Column({ type: 'text', nullable: true })
  description?: string;

  @ApiProperty({ description: '创建者ID' })
  @Column({ type: 'varchar', length: 100 })
  creatorId: string;

  @ApiProperty({ description: '创建者IP地址' })
  @Column({ type: 'varchar', length: 45 })
  creatorIp: string;

  @ApiProperty({ description: '最大参与者数量' })
  @Column({ type: 'int', default: 2 })
  maxParticipants: number;

  @ApiProperty({ description: '当前参与者数量' })
  @Column({ type: 'int', default: 0 })
  currentParticipants: number;

  @ApiProperty({ description: '房间状态' })
  @Column({
    type: 'enum',
    enum: ['waiting', 'active', 'ended'],
    default: 'waiting',
  })
  status: 'waiting' | 'active' | 'ended';

  @ApiProperty({ description: '是否需要密码' })
  @Column({ type: 'boolean', default: false })
  requiresPassword: boolean;

  @ApiProperty({ description: '房间密码哈希', required: false })
  @Column({ type: 'varchar', length: 255, nullable: true })
  passwordHash?: string;

  @ApiProperty({ description: '房间配置' })
  @Column({ type: 'jsonb', nullable: true })
  settings?: {
    audioEnabled?: boolean;
    videoEnabled?: boolean;
    screenShareEnabled?: boolean;
    chatEnabled?: boolean;
    recordingEnabled?: boolean;
  };

  @ApiProperty({ description: '房间元数据' })
  @Column({ type: 'jsonb', nullable: true })
  metadata?: {
    userAgent?: string;
    browser?: string;
    platform?: string;
    [key: string]: any;
  };

  @ApiProperty({ description: '房间过期时间' })
  @Column({ type: 'timestamp with time zone' })
  expiresAt: Date;

  @ApiProperty({ description: '最后活动时间' })
  @Column({
    type: 'timestamp with time zone',
    default: () => 'CURRENT_TIMESTAMP',
  })
  lastActivityAt: Date;

  @ApiProperty({ description: '创建时间' })
  @CreateDateColumn()
  createdAt: Date;

  @ApiProperty({ description: '更新时间' })
  @UpdateDateColumn()
  updatedAt: Date;

  @ApiProperty({ description: '参与者列表', type: () => [Participant] })
  @OneToMany(() => Participant, participant => participant.room, {
    cascade: true,
    eager: false,
  })
  participants: Participant[];

  // 虚拟属性
  get isExpired(): boolean {
    return new Date() > this.expiresAt;
  }

  get isFull(): boolean {
    return this.currentParticipants >= this.maxParticipants;
  }

  get isActive(): boolean {
    return this.status === 'active' && !this.isExpired;
  }

  get canJoin(): boolean {
    return !this.isFull && !this.isExpired && this.status !== 'ended';
  }

  // 更新最后活动时间
  updateLastActivity(): void {
    this.lastActivityAt = new Date();
  }

  // 添加参与者
  addParticipant(): void {
    this.currentParticipants += 1;
    this.updateLastActivity();
    if (this.currentParticipants > 1 && this.status === 'waiting') {
      this.status = 'active';
    }
  }

  // 移除参与者
  removeParticipant(): void {
    this.currentParticipants = Math.max(0, this.currentParticipants - 1);
    this.updateLastActivity();
    if (this.currentParticipants === 0) {
      this.status = 'ended';
    }
  }

  // 设置过期时间
  setExpiryTime(minutes: number): void {
    this.expiresAt = new Date(Date.now() + minutes * 60 * 1000);
  }

  // 延长过期时间
  extendExpiryTime(minutes: number): void {
    const newExpiryTime = new Date(
      this.expiresAt.getTime() + minutes * 60 * 1000,
    );
    this.expiresAt = newExpiryTime;
  }
}
